// 浏览器检测
(function () {
    window.sys = {}; // 让外部可以访问,保存浏览器信息对象
    var ua = navigator.userAgent.toLowerCase(); // 获取浏览器信息字符串
    var s; // 浏览器信息数组,浏览器名称+版本
    (s = ua.match(/msie ([\d\.]+)/)) ? sys.ie = s[1]:
    (s = ua.match(/firefox\/([\d\.]+)/)) ? sys.firefox = s[1]:
    (s = ua.match(/chrome\/([\d\.]+)/)) ? sys.chrome = s[1]:
    (s = ua.match(/opera\/.*version\/([\d\.]+)/)) ? sys.opera = s[1]:
    (s = ua.match(/version\/([\d\.]+).*safari/)) ? sys.safari = s[1]:0; 
     
    if (/webkit/.test(ua)) {
        sys.webkit = ua.match(/webkit\/([\d.]+)/)[1];
    }
    // console.log(ua);
    // console.log(sys.webkit);
})();

// DOM加载
function addDomLoaded(fn) {

    var isReady = false;
    var timer = null;

    function doReady() {
        if (timer) {
            clearInterval(timer);
        }
        if (isReady) {
            return;
        }
        fn();
        isReady = true;
    }

    if ((sys.opera && sys.opera < 9) || (sys.firefox && sys.firefox < 3) || (sys.webkit && sys.webkit < 525)) {
        /* timer = setInterval(function() {
            //   这种方法目前主流浏览器都是判断complete 类似于 onload
            //   loaded 是加载完dom后就运行js, complete 是图片加载完后再运行js
            if (/loaded|complete/.test(document.readyState)) {
              doReady(fn);
            }
          }, 1); */
        // 上面的方法是图片加载完毕才运行js,以下这种方法是在dom加载完毕后运行
        timer = setInterval(function () {
            if (
                document &&
                document.getElementById &&
                document.getElementsByTagName &&
                document.body
            ) {
                doReady();
            }
        });
    } else if (document.addEventListener) {// W3C
        addEvent(document, 'DOMContentLoaded', function () {
            fn();
            // alert(arguments.callee); // 打印正在运行的函数
            removeEvent(document, 'DOMContentLoaded', arguments.callee); // 运行完成后删除事件绑定
        });
    }
    else if (sys.ie && sys.ie < 9) {
        // 使用doScroll 事件判断ie 的dom是否加载成功
        var timer = null;
        timer = setInterval(function () {
            try {
                document.documentElement.doScroll('left');
                doReady();
            } catch (e) {
                console.log(e);
            }
        }, 1);
    }
}

// 跨浏览器事件绑定  // 也称现代事件绑定
/* 
obj 要绑定事件的对象
event 事件名
fn 事件相应函数 */
function addEvent(obj, event, fn) {
   if (typeof obj.addEventListener != 'undefined') {
    obj.addEventListener(event,fn,false); // false 代表捕获?
   } else {
    //    创建一个存放事件的哈希表(散列表)
    // 相当于在 obj 对象中添加了一个属性
    // 保证events 只被创建一次
     if (!obj.events) {
        obj.events = {};
     } 
    //  第一次执行
     if (!obj.events[event]) {
        //  创建保存事件处理函数的数组
        // 就是所有的事件保存在 events中, events[event] 中存放某种事件的多个函数
        obj.events[event] = [];
        // 把第一次的事件处理函数存储在第一个位置上
        if(obj['on'+event]) obj.events[event][0] = fn;
    } else{
        // 同一函数注册函数进行屏蔽,不添加到计数器中
        if (addEvent.equal(obj.events[event],fn) == true) {
            return false;
        }
    }
    // 从第二次开始,用事件计数器来记录同一个事件绑定了多个函数
    obj.events[event][addEvent.ID++] = fn;
    // 把所有事件处理函数绑定到对象上
    obj['on'+event]=addEvent.exec;

   }
};

// 同一个注册函数进行屏蔽
addEvent.equal = function (es,fn) {
    for (var i in es) {
        if (es[i] == fn) {
            return true;
        }
    }
    return false;
}

addEvent.ID = 1;
// 跨浏览器删除事件绑定

addEvent.exec = function (event) {
    var e = event || addEvent.fixEvent(window.event);
    // es 事件的复数
    var es = this.events[e.type];
    // 因为 addEvent.exec 属于 obj 对象的函数,可以用this代替
    for (var i in es) {
        es[i].call(this,e);
    }
}

// 把常用的Event对象配对到W3C中去
addEvent.fixEvent = function (event) {
    event.preventDefault = addEvent.fixEvent.preventDefault;
    event.stopPropagation = addEvent.fixEvent.stopPropagation;
    event.target = event.srcElement;
    return event;
};

// IE阻止默认行为
addEvent.fixEvent.preventDefault = function () {
    this.returnValue = false;
};
// IE取消冒泡
addEvent.fixEvent.stopPropagation = function () {
    this.cacelBubble = true;
};

function removeEvent(obj,event,fn) {
    if (typeof obj.removeEventListener != 'undefined') {
        obj.removeEventListener(event,fn,false);
    } else {
        if (obj.events) {
            for (var i in obj.events[event]) {
                if (obj.events[event][i] == fn ) {
                    delete obj.events[event][i];
                }
            }   
        }
    }
}

// 跨浏览器获取视口大小 IE 8 FIREFOX CHROME
function getInner() {
    if (typeof window.innerWidth != 'undefined') {
        return {
            width: window.innerWidth,
            height: window.innerHeight
        }
    }else{
        return {
            width: document.documentElement.clientWidth,
            height: document.documentElement.clientHeight
        }
    }
}

// 跨浏览器获取Style
function getStyle(element, attr) {
    var value;
    if (typeof window.getComputedStyle != 'undefined') { // W3C
        value = window.getComputedStyle(element, null)[attr];
    }else if (typeof element.currentStyle != 'undefined') { // IE8
        value =  element.currentStyle[attr];
    }
    return value;
}

// 判断class是否存在
function hasClass(element,className) {
    return element.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
}

// 跨浏览器添加link规则
function inserRule(sheet,selectorText,cssText,position) {
    // console.log(sheet);
    // console.log(sheet.insertRule); // 兼容 IE8
    // console.log(sheet.addRule); // 兼容 W3C
    if (typeof sheet.insertRule !='undefined') { // 兼容 W3C
        sheet.insertRule(selectorText + "{" + cssText + "}",position);
    } else if(typeof sheet.addRule !='undefined') { // 兼容 IE8
        sheet.addRule(selectorText,cssText,position);
    }
    // 新版浏览器两个都支持了
    // sheet.addRule(selectorText,cssText,position); 
    // sheet.insertRule(selectorText + "{" + cssText + "}",position);
}

// 跨浏览器移除link规则
function deleteRule(sheet,position) {
    // console.log(sheet);
    // console.log(sheet.deleteRule); // 兼容 IE8
    // console.log(sheet.removeRule); // 兼容 W3C
    if (typeof sheet.deleteRule !='undefined') { // 兼容 W3C
        sheet.deleteRule(position);
    } else if(typeof sheet.removeRule !='undefined') { // 兼容 IE8
        sheet.removeRule(position);
    }
    // 新版浏览器两个都支持了
    // sheet.addRule(selectorText,cssText,position); 
    // sheet.insertRule(selectorText + "{" + cssText + "}",position);
}

// 获取 Event 对象
function getEvent(event) {
    return event || window.event;
}

// 阻止默认行为
function preDef(event) {
    var e = getEvent(event);
    if (typeof e.preventDefault != 'undefined') { // W3C
        e.preventDefault();
    }else{ // IE
        e.returnValue = false;
    }
}

// 跨浏览器获取innerText
function getInnerText (element){
    return (typeof element.textContent == 'string') ? element.textContent : element.innerText;
}

// 跨浏览器设置innerText
function setInnerText (element,text){
    if (typeof element.textContent == 'string') {
        element.textContent = text;
    }else{
        element.innerText = text;
    }
}

// 获取某一个元素到最外层顶点
function offsetTop(element) {
    var top = element.offsetTop;
    var parent = element.offsetParent;
    while (parent != null) {
        top += parent.offsetTop;
        parent = parent.offsetParent;
    }
    return top;
}

// 删除前后空格
function trim(str) {
    return str.replace(/(^\s*)|(\s*$)/g,'');
}

// 某一个值是否存在某一个数组中
function inArray(array, value) {
    for (var i in array) {
        if (array[i] === value) {
            return true;
        }
    }
}

// 滚动条清零
function scrollTop() {
    document.documentElement.scrollTop = 0; // chrome 低版本
    document.body.scrollTop = 0;
}

// 取得滚动条已经滚动的距离
function getScroll() {
    return {
        top: document.documentElement.scrollTop /* W3C */|| document.body.scrollTop /* IE7 */,
        left: document.documentElement.scrollLeft || document.body.scrollLeft
    }
}